/*
 * FXGL - JavaFX Game Library. The MIT License (MIT).
 * Copyright (c) AlmasB (almaslvl@gmail.com).
 * See LICENSE for details.
 */
package com.windea.study.kotlin.fxgl.sample.sandbox.particles

import com.almasb.fxgl.animation.*
import com.almasb.fxgl.app.*
import com.almasb.fxgl.dsl.*
import com.almasb.fxgl.entity.*
import com.almasb.fxgl.particle.*
import javafx.collections.*
import javafx.geometry.*
import javafx.scene.control.*
import javafx.scene.effect.*
import javafx.scene.layout.*
import javafx.scene.paint.*
import javafx.scene.shape.*
import javafx.scene.text.*

/**
 * Example of using particles.
 */
class ParticleSystemSample : GameApplication() {
	
	private lateinit var particleEntity: Entity
	private lateinit var emitter: ParticleEmitter
	
	override fun initSettings(settings: GameSettings) {
		settings.width = 700 + 300
		settings.height = 600
		settings.title = "ParticleSystemSample"
		settings.version = "0.1"
		settings.isProfilingEnabled = true
	}
	
	override fun initGame() {
		entityBuilder()
			.view(Rectangle(700.0, getAppHeight().toDouble()))
			.buildAndAttach()
		
		emitter = ParticleEmitters.newFireEmitter()
		
		particleEntity = entityBuilder()
			.at(((getAppWidth() - 300) / 2).toDouble(), (getAppHeight() / 2).toDouble())
			.with(ParticleComponent(emitter))
			.buildAndAttach()
	}
	
	override fun initUI() {
		val spinnerNumParticles = Spinner<Int>(0, 100, 15, 1)
		emitter.numParticlesProperty().bind(spinnerNumParticles.valueProperty())
		
		val spinnerRate = Spinner<Double>(0.0, 1.0, 1.0, 0.05)
		emitter.emissionRateProperty().bind(spinnerRate.valueProperty())
		
		val spinnerMinSize = Spinner<Double>(1.0, 100.0, 9.0, 1.0)
		emitter.minSizeProperty().bind(spinnerMinSize.valueProperty())
		
		val spinnerMaxSize = Spinner<Double>(1.0, 100.0, 12.0, 1.0)
		emitter.maxSizeProperty().bind(spinnerMaxSize.valueProperty())
		
		val spinnerVelX = Spinner<Double>(-500.0, 500.0, 0.0, 10.0)
		val spinnerVelY = Spinner<Double>(-500.0, 500.0, -30.0, 10.0)
		
		spinnerVelX.prefWidth = 65.0
		spinnerVelY.prefWidth = 65.0
		
		spinnerVelX.valueProperty().addListener { _, _, newValue -> emitter.setVelocityFunction { Point2D(newValue, spinnerVelY.value) } }
		
		spinnerVelY.valueProperty().addListener { _, _, newValue -> emitter.setVelocityFunction { Point2D(spinnerVelX.value, newValue) } }
		
		val spinnerAccelX = Spinner<Double>(-150.0, 150.0, 0.0, 10.0)
		val spinnerAccelY = Spinner<Double>(-150.0, 150.0, 0.0, 10.0)
		
		spinnerAccelX.prefWidth = 65.0
		spinnerAccelY.prefWidth = 65.0
		
		spinnerAccelX.valueProperty().addListener { _, _, newValue -> emitter.setAccelerationFunction { Point2D(newValue, spinnerAccelY.value) } }
		
		spinnerAccelY.valueProperty().addListener { _, _, newValue -> emitter.setAccelerationFunction { Point2D(spinnerAccelX.value, newValue) } }
		
		val choiceBlend = getUIFactory().newChoiceBox(
			FXCollections.observableArrayList(*BlendMode.values())
		)
		
		emitter.blendModeProperty().bind(choiceBlend.valueProperty())
		choiceBlend.value = BlendMode.ADD
		
		val choiceInterpolator = getUIFactory().newChoiceBox(
			FXCollections.observableArrayList<EasingInterpolator>(*Interpolators.values())
		)
		
		choiceInterpolator.value = Interpolators.LINEAR
		
		choiceInterpolator.valueProperty().addListener { _, _, newValue -> emitter.interpolator = newValue.EASE_OUT() }
		
		val startColor = ColorPicker(emitter.startColor as Color)
		val endColor = ColorPicker(emitter.endColor as Color)
		
		emitter.startColorProperty().bind(startColor.valueProperty())
		emitter.endColorProperty().bind(endColor.valueProperty())
		
		val vbox = VBox(10.0)
		vbox.translateX = 700.0
		vbox.children.addAll(
			HBox(10.0, Text("Vel X and Y"), spinnerVelX, spinnerVelY),
			HBox(10.0, Text("Acc X and Y"), spinnerAccelX, spinnerAccelY),
			Text("Number of Particles:"), spinnerNumParticles,
			Text("Min Size:"), spinnerMinSize,
			Text("Max Size:"), spinnerMaxSize,
			Text("Emission Rate:"), spinnerRate,
			Text("Start Color:"), startColor,
			Text("End Color:"), endColor,
			choiceBlend,
			choiceInterpolator
		)
		
		getGameScene().addUINode(vbox)
	}
}


fun main(args: Array<String>) {
	GameApplication.launch(ParticleSystemSample::class.java, args)
}

